#include "ofxIRCConnection.h"
#include "ofxIRCUser.h"
#include "ofxIRCMessageType.h"
#include "ofxIRCPrivMsg.h"

// http://oreilly.com/pub/h/1963
ofxIRCConnection::ofxIRCConnection(
	 std::string sServer
	,int nPort
	,ofxIRCUser* oUser
):
server(sServer)
,port(nPort)
,user(oUser)
{
	state = STATE_CONNECT;
}

void ofxIRCConnection::connect() {
	tcp_client.setVerbose(true);
	if (!tcp_client.setup(server, port, false)) {
		return;
	}
}

void ofxIRCConnection::update() {
	switch(state) {
		case STATE_CONNECT: {
			char* buf= new char[10];
			int total = tcp_client.receiveRawBytes(buf, 10);
			if (total != -1) {
				state = STATE_IDENTIFY;
			}
			break;
		}

		case STATE_IDENTIFY:{
			identify();
			state = STATE_JOIN;
			break;
		}

		case STATE_JOIN: {
			joinChannels();
			state = STATE_RECIEVE;
			break;
		}

		case STATE_RECIEVE: {
			receive();
			break;
		}
		default:break;
	}
}

void ofxIRCConnection::receive() {
	char* buf = new char[100];
	int total = tcp_client.receiveRawBytes(buf, 100);
	if (total == -1) {
		return;
	}
	buffer.append(buf, total);
	buffer.parse();

	// parse the buffer, fill our messages vector.
	std::vector<std::string>lines = buffer.getLines();
	for(int i = 0; i < lines.size(); ++i) {
		ofxIRCMessageType* type = factory.parse(lines.at(i));
		if (type != NULL) {
			messages.push_back(type);
		}
	}
	buffer.clear();
}

void ofxIRCConnection::addChannel(ofxIRCChannel oChannel) {
	channels.push_back(oChannel);
}

void ofxIRCConnection::joinChannels() {
	for(int i = 0; i < channels.size(); ++i) {
		tcp_client.sendRaw("JOIN #" +channels[i].getName() +"\n");
	}
}

void ofxIRCConnection::identify() {
	if (!tcp_client.sendRaw("NICK " +user->getNick() +"\n")) {
		return;
	}

	if (!tcp_client.sendRaw("USER "
				+user->getNick()
				+" 8 * : "
				+user->getName() +"\n"))
	{
		return;
	}
}

bool ofxIRCConnection::hasMessages() {
	return messages.size() > 0;
}

void ofxIRCConnection::clearMessages() {
	// @todo do we need to clean this up??
	messages.clear();
}

std::vector<ofxIRCMessageType*> ofxIRCConnection::getMessages() {
	return messages;
}
